// 使用require加载XLSX库（Electron环境）
let XLSX;
try {
    XLSX = require('xlsx');
    console.log('XLSX库通过require加载成功，版本:', XLSX.version);
} catch (error) {
    console.error('无法通过require加载XLSX库:', error);
    XLSX = null;
}

// 动态加载XLSX库的函数（备用方案）
function loadXLSX() {
    return new Promise((resolve, reject) => {
        // 如果已经通过require加载成功，直接返回
        if (XLSX) {
            resolve(XLSX);
            return;
        }

        // 检查全局XLSX对象
        if (typeof window !== 'undefined' && typeof window.XLSX !== 'undefined') {
            resolve(window.XLSX);
            return;
        }

        const script = document.createElement('script');
        script.src = './xlsx.full.min.js';
        script.onload = () => {
            if (typeof window.XLSX !== 'undefined') {
                console.log('XLSX库通过动态加载成功');
                resolve(window.XLSX);
            } else {
                reject(new Error('XLSX库加载后仍然未定义'));
            }
        };
        script.onerror = (error) => {
            console.error('XLSX库加载失败:', error);
            reject(new Error('XLSX库文件加载失败'));
        };
        document.head.appendChild(script);
    });
}

class JSONFormatterApp {
    constructor() {
        this.jsonData = null;
        this.currentArrayData = null;
        this.currentArrayPath = '';
        
        this.initializeElements();
        this.bindEvents();
        this.updateInputStatus('waiting', '等待输入');
    }

    initializeElements() {
        this.jsonInput = document.getElementById('jsonInput');
        this.jsonTree = document.getElementById('jsonTree');
        this.inputStatus = document.getElementById('inputStatus');
        this.tableSection = document.getElementById('tableSection');
        this.dataTable = document.getElementById('dataTable');
        this.tableHead = document.getElementById('tableHead');
        this.tableBody = document.getElementById('tableBody');
        this.arrayPath = document.getElementById('arrayPath');
        
        // 按钮元素
        this.clearBtn = document.getElementById('clearBtn');
        this.formatBtn = document.getElementById('formatBtn');
        this.expandAllBtn = document.getElementById('expandAllBtn');
        this.collapseAllBtn = document.getElementById('collapseAllBtn');
        this.exportBtn = document.getElementById('exportBtn');
        this.closeTableBtn = document.getElementById('closeTableBtn');
    }

    bindEvents() {
        // JSON输入实时格式化
        this.jsonInput.addEventListener('input', () => {
            this.debounce(this.handleInputChange.bind(this), 300)();
        });

        // 按钮事件
        this.clearBtn.addEventListener('click', () => this.clearInput());
        this.formatBtn.addEventListener('click', () => this.formatInput());
        this.expandAllBtn.addEventListener('click', () => this.expandAll());
        this.collapseAllBtn.addEventListener('click', () => this.collapseAll());
        this.exportBtn.addEventListener('click', () => this.exportToExcel());
        this.closeTableBtn.addEventListener('click', () => this.closeTable());

        // 键盘快捷键
        document.addEventListener('keydown', (e) => {
            if (e.ctrlKey && e.key === 'Enter') {
                this.formatInput();
            }
        });
    }

    // 防抖函数
    debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    }

    handleInputChange() {
        const input = this.jsonInput.value.trim();
        
        if (!input) {
            this.updateInputStatus('waiting', '等待输入');
            this.jsonTree.innerHTML = '';
            this.closeTable();
            return;
        }

        try {
            this.jsonData = JSON.parse(input);
            this.updateInputStatus('valid', 'JSON格式正确');
            this.renderJsonTree();
        } catch (error) {
            this.updateInputStatus('invalid', `JSON格式错误: ${error.message}`);
            this.jsonTree.innerHTML = '<div class="error-message">JSON格式错误，请检查输入</div>';
        }
    }

    updateInputStatus(type, message) {
        this.inputStatus.className = `status-indicator ${type}`;
        this.inputStatus.innerHTML = `<i class="fas fa-circle"></i> ${message}`;
    }

    clearInput() {
        this.jsonInput.value = '';
        this.jsonTree.innerHTML = '';
        this.closeTable();
        this.updateInputStatus('waiting', '等待输入');
        this.jsonData = null;
    }

    formatInput() {
        const input = this.jsonInput.value.trim();
        if (!input) return;

        try {
            const parsed = JSON.parse(input);
            this.jsonInput.value = JSON.stringify(parsed, null, 2);
            this.handleInputChange();
        } catch (error) {
            this.updateInputStatus('invalid', `JSON格式错误: ${error.message}`);
        }
    }

    renderJsonTree() {
        if (!this.jsonData) return;

        this.jsonTree.innerHTML = '';
        const rootElement = this.createTreeNode('root', this.jsonData, '');
        rootElement.classList.add('root');
        this.jsonTree.appendChild(rootElement);
    }

    createTreeNode(key, value, path) {
        const nodeElement = document.createElement('div');
        nodeElement.className = 'tree-node';

        const itemElement = document.createElement('div');
        itemElement.className = 'tree-item';

        const keySpan = document.createElement('span');
        keySpan.className = 'tree-key';
        keySpan.textContent = key !== 'root' ? `"${key}": ` : '';

        if (value === null) {
            itemElement.appendChild(keySpan);
            const valueSpan = document.createElement('span');
            valueSpan.className = 'tree-value null';
            valueSpan.textContent = 'null';
            itemElement.appendChild(valueSpan);
            nodeElement.appendChild(itemElement);
        } else if (typeof value === 'object') {
            if (Array.isArray(value)) {
                // 数组处理
                itemElement.classList.add('array-item');
                
                // 创建折叠按钮
                const toggleButton = document.createElement('span');
                toggleButton.className = 'tree-toggle';
                toggleButton.textContent = '-';
                itemElement.appendChild(toggleButton);
                
                itemElement.appendChild(keySpan);
                
                const arrayInfo = document.createElement('span');
                arrayInfo.className = 'tree-type';
                arrayInfo.textContent = `Array(${value.length}) - 点击查看表格`;
                itemElement.appendChild(arrayInfo);

                // 创建子节点容器
                const childrenContainer = document.createElement('div');
                childrenContainer.className = 'tree-children';

                value.forEach((item, index) => {
                    const childPath = path ? `${path}[${index}]` : `${key}[${index}]`;
                    const childNode = this.createTreeNode(index, item, childPath);
                    childrenContainer.appendChild(childNode);
                });

                // 添加数组选择功能 - 绑定到整个item元素，但排除toggle按钮
                itemElement.addEventListener('click', (e) => {
                    // 如果点击的是toggle按钮，不触发数组表格显示
                    if (e.target === toggleButton) {
                        return;
                    }
                    e.stopPropagation();
                    this.showArrayTable(value, path || key);
                });

                // 折叠/展开功能 - 只绑定到toggle按钮
                toggleButton.addEventListener('click', (e) => {
                    e.stopPropagation();
                    this.toggleNode(toggleButton, childrenContainer);
                });

                nodeElement.appendChild(itemElement);
                nodeElement.appendChild(childrenContainer);

            } else {
                // 对象处理
                // 创建折叠按钮
                const toggleButton = document.createElement('span');
                toggleButton.className = 'tree-toggle';
                toggleButton.textContent = '-';
                itemElement.appendChild(toggleButton);
                
                itemElement.appendChild(keySpan);
                
                const objectInfo = document.createElement('span');
                objectInfo.className = 'tree-type';
                objectInfo.textContent = `Object(${Object.keys(value).length})`;
                itemElement.appendChild(objectInfo);

                // 创建子节点容器
                const childrenContainer = document.createElement('div');
                childrenContainer.className = 'tree-children';

                Object.entries(value).forEach(([childKey, childValue]) => {
                    const childPath = path ? `${path}.${childKey}` : `${key}.${childKey}`;
                    const childNode = this.createTreeNode(childKey, childValue, childPath);
                    childrenContainer.appendChild(childNode);
                });

                // 折叠/展开功能
                toggleButton.addEventListener('click', (e) => {
                    e.stopPropagation();
                    this.toggleNode(toggleButton, childrenContainer);
                });

                nodeElement.appendChild(itemElement);
                nodeElement.appendChild(childrenContainer);
            }
        } else {
            // 基础类型处理
            itemElement.appendChild(keySpan);
            
            const valueSpan = document.createElement('span');
            valueSpan.className = `tree-value ${typeof value}`;
            
            if (typeof value === 'string') {
                valueSpan.textContent = `"${value}"`;
            } else {
                valueSpan.textContent = String(value);
            }
            
            itemElement.appendChild(valueSpan);
            nodeElement.appendChild(itemElement);
        }

        return nodeElement;
    }

    toggleNode(toggleButton, childrenContainer) {
        const isExpanded = childrenContainer.style.display !== 'none';
        
        if (isExpanded) {
            childrenContainer.style.display = 'none';
            toggleButton.textContent = '+';
        } else {
            childrenContainer.style.display = 'block';
            toggleButton.textContent = '-';
        }
    }

    expandAll() {
        const allToggles = this.jsonTree.querySelectorAll('.tree-toggle');
        const allChildren = this.jsonTree.querySelectorAll('.tree-children');
        
        allToggles.forEach(toggle => toggle.textContent = '-');
        allChildren.forEach(children => children.style.display = 'block');
    }

    collapseAll() {
        const allToggles = this.jsonTree.querySelectorAll('.tree-toggle');
        const allChildren = this.jsonTree.querySelectorAll('.tree-children');
        
        allToggles.forEach(toggle => toggle.textContent = '+');
        allChildren.forEach(children => children.style.display = 'none');
    }

    showArrayTable(arrayData, path) {
        if (!arrayData || !Array.isArray(arrayData) || arrayData.length === 0) {
            alert('数组为空或无效');
            return;
        }

        this.currentArrayData = arrayData;
        this.currentArrayPath = path;
        this.arrayPath.textContent = path;

        // 分析数组结构，获取所有可能的键
        const allKeys = new Set();
        arrayData.forEach(item => {
            if (typeof item === 'object' && item !== null) {
                Object.keys(item).forEach(key => allKeys.add(key));
            }
        });

        // 如果数组包含基础类型，添加默认列
        if (arrayData.some(item => typeof item !== 'object' || item === null)) {
            allKeys.add('value');
        }

        const keys = Array.from(allKeys);

        // 创建表格头部
        this.tableHead.innerHTML = '';
        const headerRow = document.createElement('tr');
        keys.forEach(key => {
            const th = document.createElement('th');
            th.textContent = key;
            headerRow.appendChild(th);
        });
        this.tableHead.appendChild(headerRow);

        // 创建表格内容
        this.tableBody.innerHTML = '';
        arrayData.forEach((item, index) => {
            const row = document.createElement('tr');
            
            keys.forEach(key => {
                const td = document.createElement('td');
                
                if (key === 'value' && (typeof item !== 'object' || item === null)) {
                    // 基础类型处理
                    td.textContent = item === null ? 'null' : String(item);
                } else if (typeof item === 'object' && item !== null) {
                    // 对象类型处理
                    const value = item[key];
                    if (value === undefined) {
                        td.textContent = '';
                    } else if (value === null) {
                        td.textContent = 'null';
                    } else if (typeof value === 'object') {
                        td.textContent = JSON.stringify(value);
                    } else {
                        td.textContent = String(value);
                    }
                } else {
                    td.textContent = '';
                }
                
                row.appendChild(td);
            });
            
            this.tableBody.appendChild(row);
        });

        // 显示表格区域
        this.tableSection.style.display = 'block';
        this.tableSection.scrollIntoView({ behavior: 'smooth' });
    }

    closeTable() {
        this.tableSection.style.display = 'none';
        this.currentArrayData = null;
        this.currentArrayPath = '';
    }

    async exportToExcel() {
        if (!this.currentArrayData) {
            alert('没有数据可导出');
            return;
        }

        // 首先尝试Excel导出
        const success = await this.tryExcelExport();
        if (success) {
            return;
        }

        // 如果Excel导出失败，使用CSV导出
        console.log('Excel导出失败，尝试CSV导出...');
        this.exportToCSV();
    }

    async tryExcelExport() {
        try {
            console.log('开始导出Excel...');
            console.log('当前数组数据:', this.currentArrayData);

            // 动态加载XLSX库
            const XLSX = await loadXLSX();
            console.log('XLSX库版本:', XLSX.version);

            // 创建工作簿
            const workbook = XLSX.utils.book_new();
            console.log('工作簿创建成功');
            
            // 准备数据
            const tableData = [];
            
            // 获取表头
            const headers = Array.from(this.tableHead.querySelectorAll('th')).map(th => th.textContent.trim());
            console.log('表头:', headers);
            
            if (headers.length === 0) {
                throw new Error('无法获取表格头部信息');
            }
            
            tableData.push(headers);

            // 获取表格数据
            const rows = Array.from(this.tableBody.querySelectorAll('tr'));
            console.log('数据行数:', rows.length);
            
            if (rows.length === 0) {
                throw new Error('没有数据行可导出');
            }

            rows.forEach((row, index) => {
                const rowData = Array.from(row.querySelectorAll('td')).map(td => {
                    let content = td.textContent.trim();
                    // 将所有内容都保存为字符串，避免数字被转换为科学计数法
                    // 特殊处理null和空值
                    if (content === 'null' || content === '') {
                        return '';
                    }
                    // 所有其他内容都作为字符串返回
                    return content;
                });
                tableData.push(rowData);
                console.log(`行 ${index + 1}:`, rowData);
            });

            console.log('准备创建工作表，总数据行数:', tableData.length);

            // 创建工作表
            const worksheet = XLSX.utils.aoa_to_sheet(tableData);
            console.log('工作表创建成功');
            
            // 设置所有单元格为文本格式，防止数字被自动转换
            const range = XLSX.utils.decode_range(worksheet['!ref']);
            for (let row = range.s.r; row <= range.e.r; row++) {
                for (let col = range.s.c; col <= range.e.c; col++) {
                    const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
                    if (worksheet[cellAddress]) {
                        // 设置单元格类型为字符串
                        worksheet[cellAddress].t = 's';
                        // 确保值是字符串
                        if (typeof worksheet[cellAddress].v !== 'string') {
                            worksheet[cellAddress].v = String(worksheet[cellAddress].v);
                        }
                    }
                }
            }
            console.log('单元格格式设置完成');
            
            // 设置列宽
            const columnWidths = headers.map(header => ({ 
                width: Math.max(header.length * 1.2, 15) // 增加最小宽度以适应长数字
            }));
            worksheet['!cols'] = columnWidths;
            console.log('列宽设置完成');

            // 清理工作表名称
            const sheetName = this.sanitizeSheetName(this.currentArrayPath) || 'Array_Data';
            console.log('工作表名称:', sheetName);
            
            // 添加工作表到工作簿
            XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
            console.log('工作表添加到工作簿成功');

            // 生成文件名
            const timestamp = new Date().toISOString().slice(0, 19).replace(/[:-]/g, '');
            const fileName = `${sheetName}_${timestamp}.xlsx`;
            
            console.log('准备写入文件:', fileName);
            
            // 使用Blob方式导出Excel文件
            const workbookOutput = XLSX.write(workbook, {
                bookType: 'xlsx',
                type: 'array'
            });
            
            // 创建Blob
            const blob = new Blob([workbookOutput], {
                type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
            });
            
            // 创建下载链接
            const link = document.createElement('a');
            const url = URL.createObjectURL(blob);
            link.setAttribute('href', url);
            link.setAttribute('download', fileName);
            link.style.visibility = 'hidden';
            
            // 添加到DOM并触发下载
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            
            // 清理URL对象
            URL.revokeObjectURL(url);

            console.log('Excel文件导出成功:', fileName);
            
            // 显示成功消息
            this.showSuccessMessage(`Excel文件已导出: ${fileName} (所有字段已保存为文本格式)`);
            return true;

        } catch (error) {
            console.error('Excel导出失败:', error);
            return false;
        }
    }

    exportToCSV() {
        try {
            console.log('开始CSV导出...');
            
            // 获取表头
            const headers = Array.from(this.tableHead.querySelectorAll('th')).map(th => th.textContent.trim());
            
            if (headers.length === 0) {
                throw new Error('无法获取表格头部信息');
            }

            // 获取表格数据
            const rows = Array.from(this.tableBody.querySelectorAll('tr'));
            
            if (rows.length === 0) {
                throw new Error('没有数据行可导出');
            }

            // 构建CSV内容
            let csvContent = '';
            
            // 添加表头（处理包含逗号的字段）
            csvContent += headers.map(header => this.escapeCSVField(header)).join(',') + '\n';
            
            // 添加数据行
            rows.forEach(row => {
                const rowData = Array.from(row.querySelectorAll('td')).map(td => {
                    return this.escapeCSVField(td.textContent.trim());
                });
                csvContent += rowData.join(',') + '\n';
            });

            // 创建Blob并下载
            const blob = new Blob(['\uFEFF' + csvContent], { type: 'text/csv;charset=utf-8;' });
            const link = document.createElement('a');
            
            if (link.download !== undefined) {
                const url = URL.createObjectURL(blob);
                link.setAttribute('href', url);
                
                // 生成文件名
                const timestamp = new Date().toISOString().slice(0, 19).replace(/[:-]/g, '');
                const sheetName = this.sanitizeSheetName(this.currentArrayPath) || 'Array_Data';
                const fileName = `${sheetName}_${timestamp}.csv`;
                
                link.setAttribute('download', fileName);
                link.style.visibility = 'hidden';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                
                console.log('CSV文件导出成功:', fileName);
                this.showSuccessMessage(`CSV文件已导出: ${fileName} (Excel导出失败，已使用CSV格式)`);
            }

        } catch (error) {
            console.error('CSV导出也失败了:', error);
            alert(`导出失败: ${error.message}\n\n请查看控制台获取详细信息`);
        }
    }

    // CSV字段转义函数
    escapeCSVField(field) {
        if (field == null) return '';
        
        const stringField = String(field);
        
        // 如果字段包含逗号、引号或换行符，需要用引号包围并转义内部引号
        if (stringField.includes(',') || stringField.includes('"') || stringField.includes('\n')) {
            return '"' + stringField.replace(/"/g, '""') + '"';
        }
        
        return stringField;
    }

    // 清理工作表名称，移除不允许的字符
    sanitizeSheetName(name) {
        if (!name) return 'Array_Data';
        
        // Excel工作表名称不能包含这些字符: \ / ? * [ ]
        return name.replace(/[\\\/\?\*\[\]]/g, '_').substring(0, 31);
    }

    showSuccessMessage(message) {
        // 创建成功消息提示
        const messageElement = document.createElement('div');
        messageElement.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background: #27ae60;
            color: white;
            padding: 15px 20px;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
            z-index: 9999;
            font-size: 14px;
            animation: slideIn 0.3s ease-out;
        `;
        messageElement.textContent = message;

        // 添加动画样式
        const style = document.createElement('style');
        style.textContent = `
            @keyframes slideIn {
                from { transform: translateX(100%); opacity: 0; }
                to { transform: translateX(0); opacity: 1; }
            }
        `;
        document.head.appendChild(style);

        document.body.appendChild(messageElement);

        // 3秒后自动移除
        setTimeout(() => {
            messageElement.remove();
            style.remove();
        }, 3000);
    }
}

// 初始化应用程序
document.addEventListener('DOMContentLoaded', () => {
    new JSONFormatterApp();
}); 